package health

import (
	"fmt"
	"go/build"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// DependencyChecker 依赖检查器
type DependencyChecker struct {
	projectRoot string
}

// DependencyStatus 依赖状态
type DependencyStatus struct {
	GoModules      []ModuleInfo  `json:"go_modules"`
	MissingModules []string      `json:"missing_modules"`
	SystemPackages []PackageInfo `json:"system_packages"`
	Checks         []CheckResult `json:"checks"`
	Overall        CheckStatus   `json:"overall"`
}

// ModuleInfo Go模块信息
type ModuleInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
	Status  string `json:"status"`
}

// PackageInfo 系统包信息
type PackageInfo struct {
	Name      string `json:"name"`
	Available bool   `json:"available"`
	Version   string `json:"version,omitempty"`
}

// NewDependencyChecker 创建依赖检查器
func NewDependencyChecker(projectRoot string) *DependencyChecker {
	return &DependencyChecker{
		projectRoot: projectRoot,
	}
}

// CheckDependencies 检查依赖
func (dc *DependencyChecker) CheckDependencies() *DependencyStatus {
	status := &DependencyStatus{
		GoModules:      []ModuleInfo{},
		MissingModules: []string{},
		SystemPackages: []PackageInfo{},
		Checks:         []CheckResult{},
	}

	// 检查Go模块
	dc.checkGoModules(status)

	// 检查系统依赖
	dc.checkSystemPackages(status)

	// 检查构建环境
	dc.checkBuildEnvironment(status)

	// 计算总体状态
	dc.calculateOverallStatus(status)

	return status
}

// checkGoModules 检查Go模块
func (dc *DependencyChecker) checkGoModules(status *DependencyStatus) {
	result := CheckResult{
		Name: "Go模块检查",
	}

	// 读取go.mod文件
	goModPath := filepath.Join(dc.projectRoot, "go.mod")
	if _, err := os.Stat(goModPath); os.IsNotExist(err) {
		result.Status = StatusFail
		result.Message = "go.mod文件不存在"
		result.Suggestion = "请运行 'go mod init' 初始化模块"
		status.Checks = append(status.Checks, result)
		return
	}

	// 读取go.mod内容
	content, err := os.ReadFile(goModPath)
	if err != nil {
		result.Status = StatusFail
		result.Message = fmt.Sprintf("无法读取go.mod文件: %v", err)
		status.Checks = append(status.Checks, result)
		return
	}

	// 解析依赖
	modules := dc.parseGoMod(string(content))
	status.GoModules = modules

	// 检查关键依赖
	requiredModules := []string{
		"gopkg.in/yaml.v3",
	}

	missingCount := 0
	for _, required := range requiredModules {
		found := false
		for _, module := range modules {
			if module.Name == required {
				found = true
				break
			}
		}
		if !found {
			status.MissingModules = append(status.MissingModules, required)
			missingCount++
		}
	}

	if missingCount == 0 {
		result.Status = StatusPass
		result.Message = fmt.Sprintf("找到 %d 个Go模块，所有必需依赖都存在", len(modules))
	} else {
		result.Status = StatusFail
		result.Message = fmt.Sprintf("缺少 %d 个必需依赖: %v", missingCount, status.MissingModules)
		result.Suggestion = "请运行 'go mod tidy' 安装缺失依赖"
	}

	status.Checks = append(status.Checks, result)
}

// checkSystemPackages 检查系统包
func (dc *DependencyChecker) checkSystemPackages(status *DependencyStatus) {
	result := CheckResult{
		Name: "系统包检查",
	}

	// 检查可选的系统依赖
	systemPackages := []string{
		"git",  // 版本控制
		"curl", // HTTP客户端
		"upx",  // 可执行文件压缩
	}

	availableCount := 0
	for _, pkg := range systemPackages {
		available := dc.isSystemPackageAvailable(pkg)
		packageInfo := PackageInfo{
			Name:      pkg,
			Available: available,
		}

		if available {
			availableCount++
			packageInfo.Version = dc.getSystemPackageVersion(pkg)
		}

		status.SystemPackages = append(status.SystemPackages, packageInfo)
	}

	if availableCount == len(systemPackages) {
		result.Status = StatusPass
		result.Message = fmt.Sprintf("所有 %d 个系统包都可用", len(systemPackages))
	} else if availableCount > 0 {
		result.Status = StatusWarning
		result.Message = fmt.Sprintf("%d/%d 个系统包可用", availableCount, len(systemPackages))
		result.Suggestion = "部分功能可能受限，建议安装缺失的系统包"
	} else {
		result.Status = StatusWarning
		result.Message = "未找到可选的系统包"
		result.Suggestion = "基本功能不受影响，但建议安装git、curl等工具"
	}

	status.Checks = append(status.Checks, result)
}

// checkBuildEnvironment 检查构建环境
func (dc *DependencyChecker) checkBuildEnvironment(status *DependencyStatus) {
	result := CheckResult{
		Name: "构建环境检查",
	}

	// 检查GOPATH和GOROOT
	goroot := build.Default.GOROOT
	gopath := build.Default.GOPATH

	details := map[string]interface{}{
		"GOROOT": goroot,
		"GOPATH": gopath,
		"GOOS":   build.Default.GOOS,
		"GOARCH": build.Default.GOARCH,
	}

	if goroot == "" {
		result.Status = StatusFail
		result.Message = "GOROOT未设置"
		result.Suggestion = "请正确安装Go并设置环境变量"
	} else {
		result.Status = StatusPass
		result.Message = "Go构建环境正常"
	}

	result.Details = details
	status.Checks = append(status.Checks, result)
}

// calculateOverallStatus 计算总体状态
func (dc *DependencyChecker) calculateOverallStatus(status *DependencyStatus) {
	hasFailure := false
	hasWarning := false

	for _, check := range status.Checks {
		switch check.Status {
		case StatusFail:
			hasFailure = true
		case StatusWarning:
			hasWarning = true
		}
	}

	if hasFailure {
		status.Overall = StatusFail
	} else if hasWarning {
		status.Overall = StatusWarning
	} else {
		status.Overall = StatusPass
	}
}

// parseGoMod 解析go.mod文件
func (dc *DependencyChecker) parseGoMod(content string) []ModuleInfo {
	modules := []ModuleInfo{}
	lines := strings.Split(content, "\n")

	inRequireBlock := false
	for _, line := range lines {
		line = strings.TrimSpace(line)

		if strings.HasPrefix(line, "require (") {
			inRequireBlock = true
			continue
		}

		if inRequireBlock && line == ")" {
			inRequireBlock = false
			continue
		}

		if inRequireBlock || strings.HasPrefix(line, "require ") {
			// 解析依赖行
			if module := dc.parseModuleLine(line); module.Name != "" {
				modules = append(modules, module)
			}
		}
	}

	return modules
}

// parseModuleLine 解析模块行
func (dc *DependencyChecker) parseModuleLine(line string) ModuleInfo {
	line = strings.TrimSpace(line)
	line = strings.TrimPrefix(line, "require ")

	// 移除注释
	if idx := strings.Index(line, "//"); idx != -1 {
		line = line[:idx]
	}

	parts := strings.Fields(line)
	if len(parts) >= 2 {
		return ModuleInfo{
			Name:    parts[0],
			Version: parts[1],
			Status:  "available",
		}
	}

	return ModuleInfo{}
}

// isSystemPackageAvailable 检查系统包是否可用
func (dc *DependencyChecker) isSystemPackageAvailable(packageName string) bool {
	// 简化实现：检查PATH中是否存在可执行文件
	_, err := exec.LookPath(packageName)
	return err == nil
}

// getSystemPackageVersion 获取系统包版本
func (dc *DependencyChecker) getSystemPackageVersion(packageName string) string {
	// 简化实现，返回"available"
	return "available"
}
